package cn.edu.xhu.library_management.area.service.impl;

import cn.edu.xhu.library_management.area.entity.LmArea;
import cn.edu.xhu.library_management.area.entity.LmBookRack;
import cn.edu.xhu.library_management.area.entity.LmFloor;
import cn.edu.xhu.library_management.area.entity.LmInfo;
import cn.edu.xhu.library_management.area.entity.dto.BookRackLocationDTO;
import cn.edu.xhu.library_management.area.entity.search.LmBookRackSearch;
import cn.edu.xhu.library_management.area.entity.vo.LmBookRackVo;
import cn.edu.xhu.library_management.area.mapper.AreaMapper;
import cn.edu.xhu.library_management.area.mapper.BookRackMapper;
import cn.edu.xhu.library_management.area.mapper.FloorMapper;
import cn.edu.xhu.library_management.area.mapper.InfoMapper;
import cn.edu.xhu.library_management.area.service.BookRackService;
import cn.edu.xhu.library_management.common.entity.ResultCode;
import cn.edu.xhu.library_management.common.exception.LibraryManagementException;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.beans.Transient;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: MMJ
 * @Date: 2022 - 11 - 19
 * @Description:
 */
@Service
public class BookRackServiceImpl implements BookRackService {
    @Resource
    private FloorMapper floorMapper;
    @Resource
    private BookRackMapper bookRackMapper;
    @Resource
    private AreaMapper areaMapper;

    @Resource
    private InfoMapper infoMapper;

    @Override
    public List<LmBookRack> findBookRackByAreaId(Integer areaId) {
        return bookRackMapper.findBookRackByAreaId(areaId);
    }

    @Transactional
    @Override
    public boolean addBookRack(LmBookRack bookRack) {
        // 查询区域Id，是否存在
        LmArea area = areaMapper.findAreaById(bookRack.getAreaId());
        if (area == null) {
            throw new LibraryManagementException(ResultCode.OPERATION_ERROR, "区域Id有误");
        }
        // 查询编号和区域Id构成的主键是否重复
        LmBookRack rack = bookRackMapper.findBookRackByNumberAndAreaId(bookRack.getNumber(), bookRack.getAreaId());
        if (rack != null) {
            throw new LibraryManagementException(ResultCode.OPERATION_ERROR, "该区域书架已经存在");
        }
        // 如果容量未0 不能添加
        if (area.getRemainCapacity()<=0){
            throw new LibraryManagementException(ResultCode.OPERATION_ERROR,"该区域容量不足");
        }
        // 更改区域容量
        area.setRemainCapacity(area.getRemainCapacity()-1);
        areaMapper.updateArea(area);
        return bookRackMapper.addBookRack(bookRack) > 0;
    }

    @Transactional
    @Override
    public boolean updateBookRack(LmBookRack bookRack) {
        // 通过id查询书架是否存在
        LmBookRack rack = bookRackMapper.findBookRackById(bookRack.getId());
        if (rack == null) {
            throw new LibraryManagementException(ResultCode.OPERATION_ERROR, "书架不存在");
        }
        if (rack.equals(bookRack)) {
            // 数据一致 什么都不做
            return true;
        }
        // 查询区域Id，是否存在
        LmArea area = areaMapper.findAreaById(bookRack.getAreaId());
        if (area == null) {
            throw new LibraryManagementException(ResultCode.OPERATION_ERROR, "区域Id有误");
        }

        /**
         * 更区域的容量
         */
        // 查询修改类和查询类的区域对象是否一致
        if (!rack.getAreaId().equals(bookRack.getAreaId())){
            // 更新的两个区域不一致
            // 当前的区域容量 +1
            LmArea oldArea = areaMapper.findAreaById(rack.getAreaId());
            oldArea.setRemainCapacity(oldArea.getRemainCapacity() + 1);
            // 更新的区域容量 -1
            area.setRemainCapacity(area.getRemainCapacity() - 1);
            areaMapper.updateArea(oldArea);
            areaMapper.updateArea(area);
        }


        // 查询编号和区域Id构成的主键是否重复
        /*LmBookRack queryRack = bookRackMapper.findBookRackByNumberAndAreaId(bookRack.getNumber(), bookRack.getAreaId());
        if (queryRack != null) {
            throw new LibraryManagementException(ResultCode.OPERATION_ERROR, "该区域书架以及存在");
        }*/
        return bookRackMapper.updateBookRack(bookRack) > 0;
    }

    @Override
    public boolean deleteBookRackById(Integer id) {
        return bookRackMapper.deleteBookRackById(id) > 0;
    }

    @Override
    public Map<String, Object> search(LmBookRackSearch search) {

        Map<String, Object> list = new HashMap<>();
        List<LmBookRackVo> bookRackVoAll = new ArrayList<>();
        List<LmBookRackVo> bookRackVoFilter = new ArrayList<>();
        List<LmBookRackVo> bookRackVoRes = new ArrayList<>();
        List<LmBookRackVo> bookRackVos = new ArrayList<>();

        // 通过图书馆ID，查询对应的楼层信息
        List<LmFloor> floors = floorMapper.findFloorsByInfoId(search.getInfoId());
        floors.forEach(floor -> {
            List<LmArea> areas = areaMapper.findAreasByFloorId(floor.getId());
            areas.forEach(area -> {
                List<LmBookRack> bookRacks = bookRackMapper.findBookRackByAreaId(area.getId());
                bookRacks.forEach(bookRack -> {
                    LmBookRackVo vo = new LmBookRackVo();
                    BeanUtils.copyProperties(bookRack, vo);
                    vo.setFloorIndex(floor.getIndex());
                    vo.setFloorId(floor.getId());
                    vo.setAreaNumber(area.getNumber());
                    vo.setAreaId(area.getId());
                    vo.setAreaId(area.getId());
                    bookRackVoAll.add(vo);
                });
            });
        });

        bookRackVoFilter = bookRackVoAll.stream().filter(
                vo -> {
                    boolean flag = false;
                    if (search.getFloorId() != null) {
                        flag = vo.getFloorId().equals(search.getFloorId());
                    }
                    if (search.getAreaId() != null) {
                        flag = vo.getAreaId().equals(search.getAreaId());
                    }
                    if (search.getNumber() != null) {
                        flag = vo.getNumber().equals(search.getNumber());
                    }
                    if (search.getRow() != null) {
                        flag = vo.getRow().equals(search.getRow());
                    }
                    if (search.getColumn() != null) {
                        flag = vo.getColumn().equals(search.getColumn());
                    }
                    return flag;
                }).collect(Collectors.toList());
        // 判断是否第一次全部搜索
        bookRackVoRes = search.getFloorId() == null&&
                search.getAreaId() == null&&
                search.getNumber() == null&&
                search.getRow() == null&&
                search.getColumn() == null
                ? bookRackVoAll : bookRackVoFilter;

        // 如果没有分页则不设置
        if (search.getCurrentPage() != null && search.getPageSize() != null) {
            search.setCurrentPage((search.getCurrentPage() - 1) * search.getPageSize());
//            int len = bookRackVoAll.size() < search.getPageSize() ? bookRackVoAll.size() : search.getPageSize();
            int endLen = search.getCurrentPage() + search.getPageSize();
            int len = Math.min(endLen, bookRackVoRes.size());
            for (int i = search.getCurrentPage(); i < len; i++) {
                bookRackVos.add(bookRackVoRes.get(i));
            }
        } else {
            bookRackVos = bookRackVoRes;
        }
        list.put("bookRacks", bookRackVos);
        list.put("total", bookRackVoRes.size());


        return list;
    }

    @Override
    public BookRackLocationDTO findBookRackLocationById(Integer id) {
        BookRackLocationDTO dto = new BookRackLocationDTO();
        // 查询当前书架
        LmBookRack bookRack = bookRackMapper.findBookRackById(id);
        dto.setBookRackName(bookRack.getNumber());

        // 通过区域Id查询区域
        LmArea area = areaMapper.findAreaById(bookRack.getAreaId());
        dto.setAreaId(area.getId());
        dto.setAreaName(area.getNumber()+"");

        // 通过楼层id查询楼层
        LmFloor floor = floorMapper.findFloorById(area.getFloorId());
        dto.setFloorId(floor.getId());
        dto.setFloorIndex(floor.getIndex());

        // 通过图书馆id 查询图书馆
        LmInfo info = infoMapper.findInfoById(floor.getInfoId());
        dto.setInfoId(info.getId());
        dto.setLibName(info.getName());

        return dto;
    }
}
